/*
 * Copyright (c) 2022. China Mobile (SuZhou) Software Technology Co.,Ltd. All rights reserved.
 * Lakehouse is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

import { SqlExec } from '@/store/sqlconsole/types'
import { CloseOutlined } from '@vicons/antd'
import { ChevronLeft24Regular, ChevronRight24Regular } from '@vicons/fluent'
import { templateRef } from '@vueuse/core'
import { NIcon, NPopover } from 'naive-ui'
import { defineComponent, h, onMounted, PropType, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import useStatus from '../components/use-status'
import styles from './index.module.scss'

const props = {
  tabs: {
    type: Array as PropType<SqlExec[]>,
    default: []
  },
  active: {
    type: String,
    default: ''
  },
  onTabRemove: {
    type: Function,
    default: () => {}
  }
}

const TabsOption = defineComponent({
  name: 'tabs-option',
  props,
  setup(props: any) {
    const { t } = useI18n()

    const activeKey = ref<string>('')
    const tabRef = ref<any>({})
    const tabNavRef = ref<any>({})
    const { switchIcon } = useStatus()
    const navs = ref<SqlExec[]>([])
    // const tabHeaderRef = ref<any>({})
    const tabHeaderTarget = templateRef<HTMLElement | null>(
      'tabHeaderRef',
      null
    )
    const tabNavTarget = templateRef<HTMLElement | null>('tabNavRef', null)
    const tabsHeaderWidth = ref<any>(undefined)
    const tabsNavWidth = ref<any>()
    const showOption = ref<boolean>(false)

    onMounted(() => {
      // calculate tabsHeader width
      tabsHeaderWidth.value = document.getElementsByClassName(
        tabHeaderTarget?.value?.classList[0] as string
      )[0].clientWidth
    })

    watch(
      () => props.active,
      () => {
        activeKey.value = props.active
      },
      {
        immediate: true
      }
    )

    watch(
      () => tabsHeaderWidth.value,
      () => {
        if (tabNavTarget?.value?.classList[0]) {
          setTimeout(() => {
            tabsNavWidth.value = document.getElementsByClassName(
              tabNavTarget?.value?.classList[0] as string
            )[0].clientWidth
          })
        }

        // if tabsHeader width > window fixed width, show scroll button and close all button.
        if (tabsHeaderWidth.value > tabsNavWidth.value - 80) {
          showOption.value = true
        } else {
          showOption.value = false
        }
      },
      {
        immediate: true,
        flush: 'pre'
      }
    )

    watch(
      () => props.tabs,
      () => {
        navs.value = props.tabs
        // in next execution cycle get updated width
        setTimeout(() => {
          tabsHeaderWidth.value = document.getElementsByClassName(
            tabHeaderTarget?.value?.classList[0] as string
          )[0].clientWidth
        })
      }
    )

    const handleChange = (index: number): any => {
      const tab = props.tabs[index] as any
      if (tab?.jobId) {
        activeKey.value = tab?.jobId
      }
    }

    const tabCls = (item: SqlExec) => {
      return item.jobId === activeKey.value
        ? [styles['tabs-item'], styles['tabs-active'], styles['tabs-focused']]
        : styles['tabs-item']
    }

    // const updateNavScroll = (index: number) => {
    //   const tabNavOffset = tabNavRef.value.offsetWidth
    //   const tabHeaderOffset = tabHeaderRef.value.offsetWidth
    //   const currentOffset = getCurrentScrollOffset()
    //   const scrollWidth = tabHeaderRef.value.children[index].scrollWidth
    //   if (tabNavOffset < tabHeaderOffset) {
    //     if (tabHeaderOffset - currentOffset < tabNavOffset) {
    //       tabHeaderRef.value.style.transform = `translateX(-${
    //         currentOffset - scrollWidth
    //       }px)`
    //     }
    //   } else {
    //     if (currentOffset > 0) {
    //       tabHeaderRef.value.style.transform = `translateX(-${0}px)`
    //     }
    //   }
    // }

    const handleClose = (jobId: string, index: number) => {
      const tab = index > 0 ? navs.value[index - 1] : navs.value[0]
      // if the removed tab is current key, then activeKey shift to previous tab
      if (activeKey.value === jobId) {
        activeKey.value = tab.jobId
      }
      props.onTabRemove(jobId)
      // every remove option will scroll tab
      // navOffset > headerOffset not scroll
      // updateNavScroll(index)
    }

    // const handleCloseAll = () => {
    //   navs.value.forEach((nav: SqlExec, index: number) => {
    //     if (index !== 0) {
    //       props.onTabRemove(nav.jobId)
    //     }
    //   })
    //   activeKey.value = 'job_history'
    //   // when all tabs closed, shift to offset 0
    //   tabHeaderRef.value.style.transform = 'translateX(-0px)'
    //   showOption.value = false
    // }

    // const getCurrentScrollOffset = () => {
    //   return tabHeaderRef.value.style.transform
    //     ? Number(
    //         tabHeaderRef.value.style.transform.match(
    //           /translateX\([-]?(\d+(\.\d+)*)px\)/
    //         )[1]
    //       )
    //     : 0
    // }

    // const scrollLeft = () => {
    //   const baseOffset = 300
    //   // get current offset
    //   const currentOffset = getCurrentScrollOffset()
    //   let newOffset = 0
    //   if (currentOffset - baseOffset > 0) {
    //     newOffset = currentOffset - baseOffset
    //   } else {
    //     newOffset = 0
    //   }
    //   tabHeaderRef.value.style.transform = `translateX(-${newOffset}px)`
    // }

    // const scrollRight = () => {
    //   // check width value, and use translateX to set width
    //   const baseOffset = 300
    //   const tabNavOffset = tabNavRef.value.offsetWidth
    //   const tabHeaderOffset = tabHeaderRef.value.offsetWidth
    //   // get current offset
    //   const currentOffset = getCurrentScrollOffset()
    //   let newOffset = 0
    //   if (tabHeaderOffset - tabNavOffset - currentOffset > 0) {
    //     newOffset = currentOffset + baseOffset
    //   } else {
    //     newOffset = currentOffset
    //   }
    //   tabHeaderRef.value.style.transform = `translateX(-${newOffset}px)`
    // }

    return {
      t,
      tabRef,
      navs,
      // tabHeaderRef,
      tabNavRef,
      activeKey,
      showOption,
      handleChange,
      switchIcon,
      tabCls,
      // scrollLeft,
      // scrollRight,
      handleClose
      // handleCloseAll
    }
  },
  render() {
    return (
      <div class={styles.tabsOption} ref='tabRef'>
        <div class={styles['tabs-nav']} ref='tabNavRef'>
          <div class={styles['tabs-header']} ref='tabHeaderRef'>
            {this.navs.map((nav: SqlExec, index: number) => {
              return (
                <div
                  class={this.tabCls(nav)}
                  key={nav.jobId}
                  onClick={() => this.handleChange(index)}
                >
                  {this.switchIcon(nav.status || 'UNKNOWN')}
                  <span class={styles['tab-label']}>
                    {nav.jobId !== 'job_history' ? (
                      <NPopover placement='top' trigger={'hover'}>
                        {{
                          trigger: () =>
                            h('span', null, {
                              default: () =>
                                nav.label === 'execution history'
                                  ? this.t('explore.execution_history')
                                  : nav.label
                            }),
                          default: () =>
                            h('span', null, {
                              default: () => nav.sql
                            })
                        }}
                      </NPopover>
                    ) : (
                      <span>
                        {nav.label === 'execution history'
                          ? this.t('explore.execution_history')
                          : nav.label}
                      </span>
                    )}
                  </span>
                  <span
                    class={styles['tab-close']}
                    onClick={() => this.handleClose(nav.jobId, index)}
                  >
                    {nav.jobId !== 'job_history' ? (
                      <NIcon color='#0e7a0d' class={styles.icon}>
                        <CloseOutlined />
                      </NIcon>
                    ) : null}
                  </span>
                </div>
              )
            })}
          </div>
          <div class={styles['tabs-option']} v-show={this.showOption}>
            <NIcon class={styles.icon}>
              <ChevronLeft24Regular />
            </NIcon>
            <NIcon class={styles.icon}>
              <ChevronRight24Regular />
            </NIcon>
            <NIcon class={styles.icon}>
              <CloseOutlined />
            </NIcon>
          </div>
        </div>
        <div class={styles.contentClasses}>
          {this.$slots.default?.(this.activeKey)}
        </div>
      </div>
    )
  }
})

export default TabsOption
